#include "serverUi.h"
#include "terminal.h"

using namespace std;
using namespace CTUI;

ServerUI::ServerUI(std::string addr, int port) 
            : m_length(0)
            , m_startPos(0)
            , m_horizontalBorder('*')
            , m_verticalBorder('*')
            , m_addr(addr)
            , m_port(port)
            , m_tcpServer(addr, port)
            , m_clientCount(0)
            , m_msgCount(2)
{
    setBorderWidth(64);

    welcomeUI();
}

ServerUI::~ServerUI()
{
}

void ServerUI::run()
{
    while (true)
    {
        std::cout << "> ";
        string str;
        std::cin >> str;
        std::flush(std::cout);
        if(str.empty())
            continue;
        if(str == "q" || str == "Q") {
            // 退出线程
            ServerCmdMessage msg;
            msg.type = SC_EXIT;
            msg.send();

            exit(0);
        }
        else if(str == "2") {
        }
        else if(str == "3") {
        }
        else {
            std::cout << "请输入有效命令！\n ";
        }
    }
}

void ServerUI::setBorderWidth(int w)
{
    if (m_length == w)
        return;

    // 1. 赋值长度
    m_length = w;

    // 2. 计算起始位置
    int tm = terminalWidth();
    if (m_length > tm)
    {
        m_length = tm;
        m_startPos = 0;
    }
    else
    {
        m_startPos = (tm - m_length) / 2;
    }

    // 3. 边框字符串
    m_borderStyle.assign(m_length, m_horizontalBorder);
}

void ServerUI::setHorizontalBorderStyle(char c)
{
    m_borderStyle.assign(m_length, m_horizontalBorder);
}

void ServerUI::setVerticalBorderStyle(char c)
{
}

void ServerUI::setMessageCount(int count)
{
    if(m_msgCount != count)
        m_msgCount = count;
}

void ServerUI::welcomeUI()
{
    CLEARSCREEN();
    string space(m_length  - 4, ' ');
    positionPrint(m_startPos, m_borderStyle);
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    borderCenterPrint(m_startPos, m_length, m_verticalBorder, "欢迎使用在线即时通讯服务器！");
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    borderPrint(m_startPos, m_length, m_verticalBorder, "\tIP 地址：" + m_addr);
    borderPrint(m_startPos, m_length, m_verticalBorder, "\t端口号：" + to_string(m_port));
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    positionPrint(m_startPos, m_borderStyle);
    borderPrint(m_startPos, m_length, m_verticalBorder, space);

    borderCenterPrint(m_startPos, m_length, m_verticalBorder, "客户端状态信息");
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    borderPrint(m_startPos, m_length, m_verticalBorder, "\t总在线数量：" + to_string(m_clientCount));
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    positionPrint(m_startPos, m_borderStyle);
    borderPrint(m_startPos, m_length, m_verticalBorder, space);

    borderCenterPrint(m_startPos, m_length, m_verticalBorder, "实时信息");
    borderPrint(m_startPos, m_length, m_verticalBorder, space);
    for(auto d : m_msgs) {
        borderPrint(m_startPos, m_length, m_verticalBorder, d);
    }
    if(m_msgs.size() > 0)
        borderPrint(m_startPos, m_length, m_verticalBorder, space);
    positionPrint(m_startPos, m_borderStyle);
}

void ServerUI::addNewMessage(const std::string& msg)
{
    // 增加新消息
    m_msgs.push_front(msg);
    if(m_msgs.size() > m_msgCount)
        m_msgs.pop_back();
}


bool ServerUI::handle(const NewClientMessage *pMsg)
{
    // cout << "fd: " << pMsg->clientFd << ", addr: " << pMsg->addr << ", port: " << pMsg->port << endl;
    string msg = "新客户端连接，IP 地址：" + pMsg->addr + ", 端口号：" + to_string(pMsg->port);
    addNewMessage(msg);
    auto newClient = [&]() {
        cout << "fd: " << pMsg->clientFd << ", addr: " << pMsg->addr << ", port: " << pMsg->port << endl;
        ++m_clientCount;
        welcomeUI();
    };

    thread t(newClient);
    t.detach();
    return true;
}

bool ServerUI::handle(const ClientDataMessage *pMsg)
{
    if(pMsg->type == CDT_CLOSE) {
        string msg = "客户端断开";
        addNewMessage(msg);
        auto clientColse = [&]() {
            --m_clientCount;
            welcomeUI();
        };

        thread t(clientColse);
        t.detach();
    }
    else if(pMsg->type == CDT_LOGIN) {
        cout << pMsg->data << endl;
    }
    return true;
}